home *** CD-ROM | disk | FTP | other *** search
/ The Programmer Disk / The Programmer Disk (Microforum).iso / xpro / bc / pro18 / common.c < prev    next >
Text File  |  1992-05-31  |  14KB  |  519 lines

  1. /**********************************************************************\
  2. *                                                                      *
  3. *  common.c -- routines common to many modules                         *
  4. *                                                                      *
  5. \**********************************************************************/
  6.  
  7. #include "defs.h"
  8.  
  9. int background;
  10.  
  11. int hidden;
  12. int visual;
  13. int vpage;
  14.  
  15. int xlimit;
  16. int ylimit;
  17.  
  18. int old_mode;
  19. int mode;
  20.  
  21. int mode06;
  22. int mode11;
  23. int mode14;
  24. int mode16;
  25.  
  26. int mode06_avail;
  27. int mode11_avail;
  28. int mode14_avail;
  29. int mode16_avail;
  30.  
  31. int mouse;
  32. int xmouse;
  33. int ymouse;
  34. int buttons;
  35.  
  36. char string[80];
  37.  
  38. /**********************************************************************\
  39. *                                                                      *
  40. *  abort_program -- called when the program can't be run               *
  41. *                                                                      *
  42. \**********************************************************************/
  43.  
  44. void abort_program(abort_code)
  45. int abort_code;
  46. {
  47.    /* reset the mode to what it was (probably mode 3) */
  48.  
  49.    fg_setmode(old_mode);
  50.    fg_reset();
  51.  
  52.    /* print a line that will stay on the screen after the program exits */
  53.  
  54.    if (abort_code == 0)
  55.      printf("\nYour system does not have enough memory to run this program.\n");
  56.    else if (abort_code == 1)
  57.      printf("\nThe font file is missing.\n");
  58.    exit(0);
  59. }
  60.  
  61.  
  62. /**********************************************************************\
  63. *                                                                      *
  64. *  draw_tbox -- draw non-graphics single line box                      *
  65. *                                                                      *
  66. \**********************************************************************/
  67.  
  68. void draw_tbox(col1,col2,row1,row2)
  69. int col1, col2, row1, row2;
  70. {
  71.    /* we are working in character space, so use rows and columns */
  72.  
  73.    register int row, col;
  74.  
  75.    /* these are the ASCII characters to make the single line box */
  76.  
  77.    static char *ul = "┌";
  78.    static char *ur = "┐";
  79.    static char *ll = "└";
  80.    static char *lr = "┘";
  81.    static char *horz = "─";
  82.    static char *vert = "│";
  83.  
  84.    /* draw the sides of the box */
  85.  
  86.    for (row = row1+1; row < row2; row++)
  87.    {
  88.       put_tstring(vert,row,col1);
  89.       put_tstring(vert,row,col2);
  90.    }
  91.  
  92.    /* draw the top and the bottom of the box */
  93.  
  94.    for (col = col1+1; col < col2; col++)
  95.    {
  96.       put_tstring(horz,row1,col);
  97.       put_tstring(horz,row2,col);
  98.    }
  99.  
  100.    /* put in the corners */
  101.  
  102.    put_tstring(ul,row1,col1);
  103.    put_tstring(ur,row1,col2);
  104.    put_tstring(ll,row2,col1);
  105.    put_tstring(lr,row2,col2);
  106. }
  107.  
  108. /**********************************************************************\
  109. *                                                                      *
  110. *  exists -- does the file exist?                                      *
  111. *                                                                      *
  112. \**********************************************************************/
  113.  
  114. exists(filename)
  115. char *filename;
  116. {
  117.    if (access(filename,0) == 0)
  118.       return(TRUE);
  119.    else
  120.       return(FALSE);
  121. }
  122.  
  123. /**********************************************************************\
  124. *                                                                      *
  125. *  flushkey -- flush out the keystroke buffer and the mouse buttons    *
  126. *                                                                      *
  127. \**********************************************************************/
  128.  
  129. void flushkey()
  130. {
  131.    int dummy;
  132.    unsigned char key, aux;
  133.  
  134.    if (mouse)
  135.    {
  136.       fg_mousebut(1,&dummy,&dummy,&dummy);
  137.       fg_mousebut(2,&dummy,&dummy,&dummy);
  138.    }
  139.  
  140.    do
  141.       fg_intkey(&key,&aux);
  142.    while (key+aux > 0);
  143. }
  144.  
  145. /**********************************************************************\
  146. *                                                                      *
  147. *          initialize -- initialize the Fastgraph environment          *
  148. *                                                                      *
  149. \**********************************************************************/
  150.  
  151. void initialize()
  152. {
  153.    register int page;
  154.  
  155.    /* Check which video modes are available */
  156.  
  157.    mode06_avail = fg_testmode(6,PAGES);
  158.    mode11_avail = fg_testmode(11,PAGES);
  159.    mode14_avail = fg_testmode(14,PAGES);
  160.    mode16_avail = fg_testmode(16,PAGES);
  161.  
  162.    /* Abort the program if none of the video modes are available */
  163.  
  164.    if (!(mode06_avail | mode11_avail | mode14_avail | mode16_avail))
  165.       abort_program(0);
  166.  
  167.    /* Save the current video mode */
  168.  
  169.    old_mode = fg_getmode();
  170.  
  171.    /* Propose the default video mode */
  172.  
  173.    if (mode16_avail)
  174.       mode = 16;
  175.    else if (mode14_avail)
  176.       mode = 14;
  177.    else if (mode11_avail)
  178.       mode = 11;
  179.    else if (mode06_avail)
  180.       mode = 6;
  181.  
  182.    /* Let the user choose one of the supported modes */
  183.  
  184.    mode = select_mode();
  185.  
  186.    /* Switch to the selected video mode */
  187.  
  188.    fg_setmode(mode);
  189.  
  190.    /* Allocate virtual pages as needed */
  191.  
  192.    for (page = 1; page < PAGES; page++)
  193.       fg_allocate(page);
  194.  
  195.    /* Set up visual and hidden pages */
  196.  
  197.    fg_sethpage(1);
  198.    visual = 0;
  199.    hidden = 1;
  200.    background = 0;
  201.  
  202.    /* Determine maximum screen space coordinates */
  203.  
  204.    xlimit = fg_getmaxx();
  205.    ylimit = fg_getmaxy();
  206.  
  207.    /* For Hercules mode, we'll only use the first 640 of 720 columns */
  208.  
  209.    if (xlimit > 639) xlimit = 639;
  210.  
  211.    /* For 640x350 EGA mode, use only as much vertical resolution as Hercules */
  212.  
  213.    if (ylimit > 347) ylimit = 347;
  214.  
  215.    /* Initialize the mouse, if present */
  216.  
  217.    init_mouse();
  218. }
  219.  
  220. /**********************************************************************\
  221. *                                                                      *
  222. *  init_mouse -- initialize the mouse if present                       *
  223. *                                                                      *
  224. \**********************************************************************/
  225.  
  226. void init_mouse()
  227. {
  228.    if (fg_mouseini() > 0)
  229.    {
  230.       mouse = TRUE;
  231.       fg_mouselim(6,xlimit-5,0,ylimit);
  232.       xmouse = xlimit / 2;
  233.       ymouse = ylimit / 2;
  234.       fg_mousemov(xmouse,ymouse);
  235.       fg_mousevis(ON);
  236.    }
  237.    else
  238.       mouse = FALSE;
  239. }
  240.  
  241. /**********************************************************************\
  242. *                                                                      *
  243. *  printer_ready -- is the printer on line?                            *
  244. *                                                                      *
  245. \**********************************************************************/
  246.  
  247. printer_ready()
  248. {
  249.    static union REGS registers;
  250.  
  251.    registers.h.ah = 2;
  252.    registers.x.dx = 0;
  253.    int86(0x17,®isters,®isters);
  254.    return(registers.h.ah == 0x90);
  255. }
  256.  
  257. /**********************************************************************\
  258. *                                                                      *
  259. *  scale -- the y in the low-res modes is 4/7th the y in hi-res modes  *
  260. *                                                                      *
  261. \**********************************************************************/
  262.  
  263. scale(y)
  264. int y;
  265. {
  266.    if (mode06 || mode14)
  267.       return((y * 4) / 7);
  268.    else
  269.       return(y);
  270. }
  271.  
  272. /**********************************************************************\
  273. *                                                                      *
  274. * select_mode -- let the user choose a supported video mode            *
  275. *                                                                      *
  276. \**********************************************************************/
  277.  
  278. select_mode()
  279. {
  280.    register int i;
  281.    unsigned char key, aux;
  282.    int current, new;
  283.  
  284.    static int max = 4;
  285.  
  286.    static char *menu_string[] = {
  287.       " CGA, MCGA, or Tandy 1000          ",
  288.       " EGA with RGB display              ",
  289.       " EGA with enhanced display, or VGA ",
  290.       " Hercules monochrome               "};
  291.  
  292.    static int menu_row[] = {10,11,12,13};
  293.  
  294.    /* use setmode to clear the screen and initialize Fastgraph */
  295.  
  296.    fg_setmode(old_mode);
  297.  
  298.    /* turn off the cursor and the NumLock key */
  299.  
  300.    fg_cursor(OFF);
  301.    fg_setnum(OFF);
  302.  
  303.    /* draw the box */
  304.  
  305.    fg_setattr(7,7,0);
  306.    fg_rect(21,59,9,14);
  307.    fg_setattr(0,7,0);
  308.    draw_tbox(22,58,9,14);
  309.  
  310.    mode06 = FALSE;
  311.    mode11 = FALSE;
  312.    mode14 = FALSE;
  313.    mode16 = FALSE;
  314.  
  315.    /* start out pointing to preferred mode for this system */
  316.  
  317.    switch(mode)
  318.    {
  319.       case 6:
  320.          current = 0;
  321.          break;
  322.       case 11:
  323.          current = 3;
  324.          break;
  325.       case 14:
  326.          current = 1;
  327.          break;
  328.       case 16:
  329.          current = 2;
  330.    }
  331.  
  332.    new = current;
  333.  
  334.    for (i = 0; i < max; i++)
  335.    {
  336.       fg_setattr(0,7,0);
  337.       put_tstring(menu_string[i],menu_row[i],23);
  338.    }
  339.    fg_setattr(15,0,0);
  340.    put_tstring(menu_string[current],menu_row[current],23);
  341.    put_tstring("Best choice -->",menu_row[current],5);
  342.  
  343.    /* get input and let the user select the mode they want */
  344.  
  345.    while (TRUE)
  346.    {
  347.       fg_getkey(&key,&aux);
  348.  
  349.       if (key == ESC)
  350.           terminate();
  351.  
  352.       else if (aux == DOWN_ARROW)
  353.       {
  354.           new = current + 1;
  355.           if (new >= max) new = 0;
  356.       }
  357.  
  358.       else if (aux == UP_ARROW)
  359.       {
  360.           new = current - 1;
  361.           if (new < 0) new = max - 1;
  362.       }
  363.  
  364.       else if (key == CR)
  365.       {
  366.          switch(current)
  367.          {
  368.             case 0:                /* CGA 2-color mode */
  369.                if (mode06_avail)
  370.                {
  371.                   mode06 = TRUE;
  372.                   return(6);
  373.                }
  374.                else
  375.                {
  376.                   fg_waitfor(1);
  377.                   fg_sound(1200,1);
  378.                   break;
  379.                }
  380.             case 1:               /* 640X200 16 color EGA & VGA */
  381.                if (mode14_avail)
  382.                {
  383.                   mode14 = TRUE;
  384.                   return(14);
  385.                }
  386.                else
  387.                {
  388.                   fg_waitfor(1);
  389.                   fg_sound(1200,1);
  390.                   break;
  391.                }
  392.             case 2:               /* 640X350 16 color EGA & VGA */
  393.                if (mode16_avail)
  394.                {
  395.                   mode16 = TRUE;
  396.                   return(16);
  397.                }
  398.                else
  399.                {
  400.                   fg_waitfor(1);
  401.                   fg_sound(1200,1);
  402.                   break;
  403.                }
  404.             case 3:               /* 720 X 348 Hercules */
  405.                if (mode11_avail)
  406.                {
  407.                   mode11 = TRUE;
  408.                   return(11);
  409.                }
  410.                else
  411.                {
  412.                   fg_waitfor(1);
  413.                   fg_sound(1200,1);
  414.                   break;
  415.                }
  416.          }
  417.       }
  418.  
  419.       /* unhighlight current string */
  420.  
  421.       fg_setattr(0,7,0);
  422.       put_tstring(menu_string[current],menu_row[current],23);
  423.  
  424.       /* highlight the new string */
  425.  
  426.       fg_setattr(15,0,0);
  427.       put_tstring(menu_string[new],menu_row[new],23);
  428.  
  429.       current = new;
  430.    }
  431. }
  432.  
  433. /**********************************************************************\
  434. *                                                                      *
  435. *  terminate -- perform necessary cleanup and return control to DOS    *
  436. *                                                                      *
  437. \**********************************************************************/
  438.  
  439. void terminate()
  440. {
  441.    register int page;
  442.  
  443.    /* Release Fastgraph's virtual video pages */
  444.  
  445.    for (page = 1; page < PAGES; page++)
  446.       fg_freepage(page);
  447.  
  448.    /* Restore the original video mode and screen attributes */
  449.  
  450.    fg_setmode(old_mode);
  451.    fg_reset();
  452.  
  453.    /* Return control to DOS */
  454.  
  455.    exit(0);
  456. }
  457.  
  458. /**********************************************************************\
  459. *                                                                      *
  460. *  wait_for_keystroke -- wait for a keystroke or mouse button          *
  461. *                                                                      *
  462. \**********************************************************************/
  463.  
  464. void wait_for_keystroke()
  465. {
  466.    int buttons;
  467.    int count;
  468.    int x, y;
  469.    unsigned char key, aux;
  470.  
  471.    flushkey();
  472.  
  473.    /* if the mouse is loaded, must loop and wait for button or keystroke */
  474.  
  475.    if (mouse)
  476.    {
  477.       fg_mousevis(ON);
  478.       while (TRUE)
  479.       {
  480.          fg_waitfor(1);
  481.          fg_intkey(&key,&aux);
  482.          if (key+aux > 0) break;
  483.          fg_mousebut(1,&count,&x,&y);
  484.          if (count > 0) break;
  485.          fg_mousebut(2,&count,&x,&y);
  486.          if (count > 0) break;
  487.       }
  488.       do
  489.          fg_mousepos(&x,&y,&buttons);
  490.       while (buttons&3);
  491.       fg_mousevis(OFF);
  492.    }
  493.  
  494.    /* if the mouse is not loaded, just wait for a key */
  495.  
  496.    else
  497.       fg_getkey(&key,&aux);
  498. }
  499.  
  500.  
  501. /**********************************************************************\
  502. *                                                                      *
  503. *  wait_for_mouse_buttons -- wait until no mouse buttons are pressed   *
  504. *                                                                      *
  505. \**********************************************************************/
  506.  
  507. void wait_for_mouse_buttons()
  508. {
  509.    int buttons;
  510.    int x, y;
  511.  
  512.    if (mouse)
  513.    {
  514.       do
  515.          fg_mousepos(&x,&y,&buttons);
  516.       while (buttons&3);
  517.    }
  518. }
  519.